package com.sunwayworld.basemodule.business.operationbatch.service.impl;

import com.sunwayworld.basemodule.business.operationbatch.bean.LimsPreTaskSupplementBean;
import com.sunwayworld.basemodule.business.operationbatch.service.LimsPreTaskSupplementService;
import com.sunwayworld.basemodule.business.prefolder.bean.LimsPreFolderBean;
import com.sunwayworld.basemodule.business.prefolder.service.LimsPreFolderService;
import com.sunwayworld.basemodule.coredata.experimentaltemplate.bean.LimsExperimentalTemplateTestBean;
import com.sunwayworld.basemodule.coredata.experimentaltemplate.service.LimsExperimentalTemplateTestService;
import com.sunwayworld.basemodule.coredata.test.bean.LimsTestSupplementBean;
import com.sunwayworld.basemodule.coredata.test.service.LimsTestSupplementService;
import com.sunwayworld.framework.utils.ArrayUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.sunwayworld.framework.at.annotation.AuditTrailType;
import com.sunwayworld.framework.at.annotation.AuditTrailEntry;
import com.sunwayworld.framework.spring.annotation.GikamBean;

import com.sunwayworld.basemodule.business.operationbatch.dao.LimsOperationBatchDao;
import com.sunwayworld.basemodule.business.operationbatch.bean.LimsOperationBatchBean;
import com.sunwayworld.basemodule.business.operationbatch.service.LimsOperationBatchService;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.restful.data.RestJsonWrapperBean;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Repository
@GikamBean
public class LimsOperationBatchServiceImpl implements LimsOperationBatchService {

    @Autowired
    private LimsPreFolderService preFolderService;

    @Autowired
    private LimsExperimentalTemplateTestService templateTestService;

    @Autowired
    private LimsTestSupplementService testSupplementService;

    @Autowired
    private LimsPreTaskSupplementService preTaskSupplementService;

    @Autowired
    private LimsOperationBatchDao limsOperationBatchDao;

    @Override
    @SuppressWarnings("unchecked")
    public LimsOperationBatchDao getDao() {
        return limsOperationBatchDao;
    }

    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.INSERT)
    public Long insert(RestJsonWrapperBean jsonWrapper) {
        LimsOperationBatchBean limsOperationBatch = jsonWrapper.parseUnique(LimsOperationBatchBean.class);
        limsOperationBatch.setId(ApplicationContextHelper.getNextIdentity());
        getDao().insert(limsOperationBatch);
        return limsOperationBatch.getId();
    }

    @Override
    @Transactional
    public void createOperationBatch(RestJsonWrapperBean wrapper) {
        List<LimsPreFolderBean> preFolderBeans = wrapper.parse(LimsPreFolderBean.class);
        if (preFolderBeans.isEmpty()) return;
        LimsOperationBatchBean operationBatchBean = new LimsOperationBatchBean();
        operationBatchBean.setId(ApplicationContextHelper.getNextIdentity());
        operationBatchBean.setOperationBatch(ApplicationContextHelper.getNextSequence("T_LIMS_OPERATION_BATCH"));
        operationBatchBean.setEtId(preFolderBeans.get(0).getEtId());
        operationBatchBean.setEtCode(preFolderBeans.get(0).getEtCode());
        operationBatchBean.setEtName(preFolderBeans.get(0).getEtName());
        // 送检实验室（暂不应），后续如果不同送检实验室需要在一个实验室下发，取送检实验室
        operationBatchBean.setBatchOrgId(preFolderBeans.get(0).getCreatedByOrgId());

        preFolderBeans.forEach(p -> {
            p.setOperationBatch(operationBatchBean.getOperationBatch());
            p.setAddInBatch("1");
        });

        // 获取运营补充信息
        List<LimsExperimentalTemplateTestBean> templateTestBeans = templateTestService.getDao().selectListByOneColumnValue(operationBatchBean.getEtId(), "etId", ArrayUtils.asList("testId"));
        List<Long> testIds = templateTestBeans.stream().map(LimsExperimentalTemplateTestBean::getTestId).distinct().collect(Collectors.toList());
        List<LimsTestSupplementBean> testSupplementBeans = testSupplementService.getDao().selectListByOneColumnValues(testIds, "testId");
        Map<String, List<LimsTestSupplementBean>> testSupplementMaps = testSupplementBeans.stream()
                .sorted(Comparator.comparingLong(LimsTestSupplementBean::getOrderNo))
                .collect(Collectors.groupingBy(LimsTestSupplementBean::getInformation));

        List<LimsPreTaskSupplementBean> preTaskSupplementBeans = new ArrayList<>();
        for (String s : testSupplementMaps.keySet()) {
            LimsTestSupplementBean bean = testSupplementMaps.get(s).get(0);
            for (LimsPreFolderBean preFolderBean : preFolderBeans) {
                LimsPreTaskSupplementBean preTaskSupplementBean = new LimsPreTaskSupplementBean();
                preTaskSupplementBean.setId(ApplicationContextHelper.getNextIdentity());
                preTaskSupplementBean.setOperationBatch(preFolderBean.getOperationBatch());
                preTaskSupplementBean.setPreFolderId(preFolderBean.getId());
                preTaskSupplementBean.setFieldName(bean.getInformation());
                preTaskSupplementBean.setFieldValue(bean.getDefaultValue());
                preTaskSupplementBean.setRequiredFlag(bean.getRequiredFlag());
                preTaskSupplementBean.setOrderNo(bean.getOrderNo());
                preTaskSupplementBean.setUnit(bean.getUnit());
                preTaskSupplementBeans.add(preTaskSupplementBean);
            }
        }

        preFolderService.getDao().fastUpdate(preFolderBeans, "operationBatch", "addInBatch");
        getDao().insert(operationBatchBean);
        preTaskSupplementService.getDao().insert(preTaskSupplementBeans);
    }

    @Override
    @Transactional
    public void deleteOperationBatch(RestJsonWrapperBean wrapper) {
        List<LimsOperationBatchBean> operationBatchBeans = wrapper.parse(LimsOperationBatchBean.class);
        if (operationBatchBeans.isEmpty()) return;
        List<String> operationBatchs = operationBatchBeans.stream().map(LimsOperationBatchBean::getOperationBatch).collect(Collectors.toList());

        List<LimsPreFolderBean> preFolderBeans = preFolderService.getDao().selectListByOneColumnValues(operationBatchs, "operationBatch", ArrayUtils.asList("id"));
        preFolderBeans.forEach(p -> {
            p.setOperationBatch(null);
            p.setAddInBatch("0");
        });

        List<Long> preFolderIds = preFolderBeans.stream().map(LimsPreFolderBean::getId).collect(Collectors.toList());
        List<LimsPreTaskSupplementBean> preTaskSupplementBeans = preTaskSupplementService.getDao().selectListByOneColumnValues(preFolderIds, "preFolderId", ArrayUtils.asList("id"));

        preFolderService.getDao().fastUpdate(preFolderBeans,"operationBatch", "addInBatch");
        preTaskSupplementService.getDao().deleteBy(preTaskSupplementBeans);
        getDao().deleteBy(operationBatchBeans);
    }
}
